package com.ytjj.qmyx.data.amqp.consumer;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.rabbitmq.client.Channel;
import com.ytjj.common.constants.PlatformConstant;
import com.ytjj.common.constants.QueueConstants;
import com.ytjj.common.constants.RedisConstants;
import com.ytjj.common.exception.ApiException;
import com.ytjj.common.utils.HttpClientUtil;
import com.ytjj.qmyx.data.client.AdminClient;
import com.ytjj.qmyx.data.config.SupplyApiConfig;
import com.ytjj.qmyx.data.mapper.ProductCopyHistoryMapper;
import com.ytjj.qmyx.data.mapper.ProductDao;
import com.ytjj.qmyx.data.model.DlListVo;
import com.ytjj.qmyx.data.model.ProductCopyHistory;
import com.ytjj.qmyx.data.model.request.ProductReviewsAddRequest;
import com.ytjj.qmyx.data.model.request.ProductReviewsUpdateRequest;
import com.ytjj.qmyx.data.model.request.ProductSelectRequest;
import com.ytjj.qmyx.data.model.request.ProductUpdateRequest;
import com.ytjj.qmyx.data.model.response.*;
import com.ytjj.qmyx.mall.mapper.ProductReviewsMapper;
import com.ytjj.qmyx.mall.model.Product;


import com.ytjj.qmyx.mall.model.ProductReviews;
import com.ytjj.qmyx.mall.model.ProductSpec;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

import static java.lang.Integer.parseInt;

/**
 * 商品选品,修改消息监听器
 * @author EDY
 */
@Slf4j
@Component
@RefreshScope
public class ProductListener {
    @Resource
    private SupplyApiConfig supplyApiConfig;
    @Resource
    private ProductDao productDao;

    @Value("${h5ShopId:GUOB004}")
    public String h5ShopId;
    @Value("${appShopId:GUOB005}")
    public String appShopId;
    @Value("${h5_2ShopId:GUOB006}")
    public String h5_2ShopId;
    @Value("${h5_3ShopId:GUOB007}")
    public String h5_3ShopId;
    @Resource
    private AdminClient adminClient;
    @Resource
    private ProductCopyHistoryMapper productCopyHistoryMapper;
    @Resource
    private ProductReviewsMapper productReviewsMapper;
    /**
     * 短链平台接口url
     */
    @Value("${short.platform.mainUrl:}")
    private String url;

    @RabbitListener(queuesToDeclare = @Queue(value = QueueConstants.PRODUCT_ADD_QUEUE, durable = "true"))
    public void selectAndAddProduces(String productDddStr, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag, Channel channel) {
        log.info("收到一条消息selectAndAddProduces消息：" + productDddStr+"");
        ProductCopyHistory productCopyHistory = saveHistory(productDddStr,1);
        ProductSelectRequest productSelectRequest = JSONObject.parseObject(productDddStr, ProductSelectRequest.class);
        Boolean flag = false;
        ArrayList<String> shopIdList = Lists.newArrayList(productSelectRequest.getShopId().split(","));
        for (String item : shopIdList) {
            if(item.contains(supplyApiConfig.getShopId().substring(0, 5))) {
                flag = true;
            }
        }
        if (productSelectRequest.getShopId().equals("all") || flag) {
            saveSelectedProducts(productSelectRequest.getIds(),productSelectRequest.getPlatformData());
        }
        productCopyHistory.setStatus(2);
        productCopyHistoryMapper.updateByPrimaryKey(productCopyHistory);
    }


    @RabbitListener(queuesToDeclare = @Queue(value = QueueConstants.PRODUCT_UPDATE_QUEUE, durable = "true"))
    public void updateProduct(String productUpdateStr, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag, Channel channel) {
        log.info("收到一条消息updateProduct消息：" + productUpdateStr+"");
        ProductCopyHistory productCopyHistory = saveHistory(productUpdateStr,2);
        ProductUpdateRequest productUpdateRequest = JSONObject.parseObject(productUpdateStr, ProductUpdateRequest.class);
        Integer id = productUpdateRequest.getId();
        Boolean flag = false;
        ArrayList<String> shopIdList = Lists.newArrayList(productUpdateRequest.getShopId().split(","));
        for (String item : shopIdList) {
            if(item.contains(supplyApiConfig.getShopId().substring(0, 5))) {
                flag = true;
            }
        }

        if (productUpdateRequest.getShopId().equals("all") || flag) {
            List<Product> channelProducts = new ArrayList<>();
            if(productUpdateRequest.getPlatformData() !=null && productUpdateRequest.getPlatformData().equals("all")) {
                channelProducts = productDao.queryBySupplyIdAndPlatformData(Lists.newArrayList(productUpdateRequest.getSupplyProductId()),null);
            } else {
                ArrayList<String> platformDataList = Lists.newArrayList(productUpdateRequest.getPlatformData().split(","));
                for (String platformData : platformDataList) {
                    channelProducts.addAll(productDao.queryBySupplyIdAndPlatformData(Lists.newArrayList(productUpdateRequest.getSupplyProductId()), platformData));
                }
            }
            log.info("需要更新商品id：{}",JSONObject.toJSONString(channelProducts));
            if (!CollectionUtils.isEmpty(channelProducts)) {
                List<Integer> productIdList = channelProducts.stream().map(Product::getId).collect(Collectors.toList());
                for (Integer productId : productIdList) {
                    productUpdateRequest.setId(productId);
                    updateGoodsDetail(productId,productUpdateRequest,id);
                }
            }
        }
        log.info("修改商品结束");
        productCopyHistory.setStatus(2);
        productCopyHistoryMapper.updateByPrimaryKey(productCopyHistory);
    }

    @Transactional(rollbackFor = Exception.class)
    public boolean saveSelectedProducts(List<Integer> ids, String platformData) {
        for (Integer supplyProductId : ids) {
            //1.2.1.查询供应链商品信息
            ProductSelectDetailResponse productSelectDetail = this.findProductSelectDetail(supplyProductId);
            if(productSelectDetail == null){
                throw new ApiException("商品不存在,请刷新重试");
            }
            List<ProductSkuKeyResponse> skuKey = productSelectDetail.getSkuKey();;
            //商品详情图和轮播图
            List<ProductImgResponse> infoAndBanner = productSelectDetail.getInfoList();
            List<ProductSpecResponse> spec =  productSelectDetail.getSpec();
            infoAndBanner.addAll(productSelectDetail.getBannerList());
            Integer freightId= productSelectDetail.getFreightId();

            if("all".equals(platformData)) {
                Boolean appFlag = saveProduct(productSelectDetail, PlatformConstant.APP_PLATFORM, freightId, skuKey, infoAndBanner, spec);
                Boolean h5Flag = saveProduct(productSelectDetail, PlatformConstant.PLATFORM_H5, freightId, skuKey, infoAndBanner, spec);
                Boolean h5_2Flag = saveProduct(productSelectDetail, PlatformConstant.H5_2_PLATFORM, freightId, skuKey, infoAndBanner, spec);
                Boolean h5_3Flag = saveProduct(productSelectDetail, PlatformConstant.H5_3_PLATFORM, freightId, skuKey, infoAndBanner, spec);
                //todo 地区销售渠道暂时不处理
                if(!appFlag || !h5Flag || !h5_2Flag || !h5_3Flag) {
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    return false;
                }
            } else {
                ArrayList<String> platformDataList = Lists.newArrayList(platformData.split(","));
                List<Boolean> booleanList = new ArrayList<>();
                for (String platformDataStr : platformDataList) {
                    booleanList.add(saveProduct(productSelectDetail, platformDataStr, freightId, skuKey, infoAndBanner, spec));
                }
                for (Boolean flag : booleanList) {
                    if(!flag) {
                        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                        return false;
                    }
                }

            }
        }
        return true;
    }

    public Boolean saveProduct(ProductSelectDetailResponse productSelectDetail,String platformData,Integer freightId,List<ProductSkuKeyResponse> skuKey,List<ProductImgResponse> infoAndBanner,List<ProductSpecResponse> spec) {
        List<Product> products = productDao.queryBySupplyProductIdAndPlatformData(productSelectDetail.getId(), platformData);
        if (!CollectionUtils.isEmpty(products)) {
            return true;
        }
        List<Integer> addIds = new ArrayList<>();
        Product product1 = new Product();
        BeanUtils.copyProperties(productSelectDetail,product1);
        product1.setId(null);
        product1.setStatus((byte)4);
        product1.setProductType(1);
        product1.setActivityType("");
        product1.setPlatformData(platformData);
        product1.setSupplyProductId(productSelectDetail.getId());
        product1.setVolume(StringUtils.isEmpty(product1.getVolumeStr()) ? 0 : parseInt(product1.getVolumeStr()));
        product1.setCreateTime(new Date());
        //新增商品
        product1.setFreightId(freightId);
        productDao.insertEntity(product1);
        //保存成功则添加到集合
        if (product1.getId() != null) {
            addIds.add(productSelectDetail.getId());
        }

        //新增商品图片
        for (ProductImgResponse productImgResponse : infoAndBanner) {
            productImgResponse.setProductId(product1.getId());
        }
        if(!CollectionUtils.isEmpty(infoAndBanner)){
            productDao.insertProductImgBatch(infoAndBanner);
        }

        //新增商品规格数据
        for (ProductSpecResponse productSpecResponse : spec) {
            productSpecResponse.setProductId(product1.getId());
            productSpecResponse.setSupplyId(productSpecResponse.getId());
        }
        if(!CollectionUtils.isEmpty(spec)){
            productDao.insertProductSpecBatch(spec);
        }

        //新增skuKey和skuKey_value
        for (ProductSkuKeyResponse productSkuKeyResponse : skuKey) {
            productSkuKeyResponse.setPid(product1.getId());
            productSkuKeyResponse.setSupplySkuKeyId(productSkuKeyResponse.getId());
            productSkuKeyResponse.setId(null);
            productDao.insertProductSkuKey(productSkuKeyResponse);
            List<ProductSkuValueResponse> skuValue = productSkuKeyResponse.getSkuValue();
            if(productSkuKeyResponse.getId() != null){
                for (ProductSkuValueResponse productSkuValueResponse : skuValue) {
                    productSkuValueResponse.setKid(productSkuKeyResponse.getId());
                    productSkuValueResponse.setPid(product1.getId());
                    productSkuValueResponse.setSupplySkuValueId(productSkuValueResponse.getId());
                    productDao.insertProductSkuValue(productSkuValueResponse);
                }
            }
        }

        return supplyProductReceive(addIds,platformData);
    }


    public ProductSelectDetailResponse findProductSelectDetail(Integer productId) {
        HashMap<String, String> map = new HashMap<>();
        map.put("id", productId.toString());
        String resultJson = HttpClientUtil.doGet(supplyApiConfig.getUrl()+"/product/findProductSelectDetail",map,supplyApiConfig.getHeadsMap());
        if(StringUtils.isEmpty(resultJson)){
            return null;
        }
        JSONObject parse = JSON.parseObject(resultJson);
        ProductSelectDetailResponse productSelectDetailResponse = JSONObject.parseObject(parse.getString("data"), ProductSelectDetailResponse.class);
        List<ProductSpecResponse> spec = productSelectDetailResponse.getSpec();
        if (!CollectionUtils.isEmpty(spec)) {
            //供货价排序
            spec = spec.stream().sorted(Comparator.comparing(ProductSpecResponse::getSupplyPrice, Comparator.nullsFirst(Comparator.naturalOrder()))).collect(Collectors.toList());
            productSelectDetailResponse.setMinPrice(String.valueOf(spec.get(0).getSupplyPrice()));
            productSelectDetailResponse.setMaxPrice(String.valueOf(spec.get(spec.size() - 1).getSupplyPrice()));
        }else {
            productSelectDetailResponse.setMinPrice("0.00");
            productSelectDetailResponse.setMaxPrice("0.00");
        }
        return productSelectDetailResponse;
    }

    public boolean supplyProductReceive(List<Integer> addIds,String platformData) {
        if (addIds.size() > 0) {
            Map<String, Object> map = new HashMap<>();
            map.put("shopId", supplyApiConfig.getShopId());
            if (PlatformConstant.PLATFORM_H5.equals(platformData)) {
                map.put("shopId", h5ShopId);
            }
            if (PlatformConstant.APP_PLATFORM.equals(platformData)){
                map.put("shopId", appShopId);
            }
            if (PlatformConstant.H5_2_PLATFORM.equals(platformData)){
                map.put("shopId", h5_2ShopId);
            }
            if (PlatformConstant.H5_3_PLATFORM.equals(platformData)){
                map.put("shopId", h5_3ShopId);
            }
            //todo 暂时不处理地区销售渠道
            map.put("productIds", addIds);
            map.put("status", 1);
            String params = JSON.toJSONString(map);
            String resultJson = HttpClientUtil.doPostJson(supplyApiConfig.getUrl() + "/product/receive", params, supplyApiConfig.getHeadsMap());
            if (StringUtils.isEmpty(resultJson) || !"200".equals(JSON.parseObject(resultJson).get("code").toString())) {
                return false;
            }
        }
        return true;
    }

    public static final String PRODUCT_DETAILS_KEY = "PRODUCT_DETAILS_KEY";
    @Transactional(rollbackFor = Exception.class)
    public void updateGoodsDetail(Integer productId,ProductUpdateRequest goodsRequest,Integer id) {
        try {
            if (goodsRequest.getIsSync()!=null && goodsRequest.getIsSync()==2) {
                productDao.deleteImg(productId,null);
                saveImg(goodsRequest);
                updateProductSpecNew(productId,goodsRequest.getSpec(),goodsRequest.getIsSync());
                //修改商品信息
                goodsRequest.setVolume(StringUtils.isEmpty(goodsRequest.getVolumeStr()) ? 0 : parseInt(goodsRequest.getVolumeStr()));
                productDao.updateGoodsNew(goodsRequest);

            } else if (goodsRequest.getIsSync()!=null && goodsRequest.getIsSync()==3) {
//                productDao.deleteImg(productId,"info");
//            saveProductImg(goodsRequest);
                productDao.deleteImg(productId,null);
                saveImg(goodsRequest);
                //修改当前商品的规格
                List<ProductSpec> productSpecs = productDao.selectByProductIds(Arrays.asList(productId));
                for (ProductSpec productSpec : productSpecs) {
                    for (ProductSpecResponse reqSpec : goodsRequest.getSpec()) {
                        if(productSpec.getSupplyId().equals(reqSpec.getSupplyId())){
                            productDao.updateSpecById(reqSpec.getProImg(),productSpec.getId());
                            break;
                        }
                    }
                }
                productDao.updateProductLongTitle(goodsRequest.getId(),goodsRequest.getLongTitle(),goodsRequest.getProductName(),goodsRequest.getProductImg());
            }
            String key = RedisConstants.PRODUCT_DETAILS + PRODUCT_DETAILS_KEY + productId;
            adminClient.deleteProductRedis(key);
        }catch (Exception e) {
            log.error("修改商品信息错误:{}",e.getMessage());
        }

    }


    public void saveImg(ProductUpdateRequest goodsRequest) {
        List<ProductImgResponse> addList = new ArrayList<>();
        List<ProductImgResponse> bannerList = goodsRequest.getBannerList();
        for (ProductImgResponse productImgRequest : bannerList) {
            if (productImgRequest.getSort() == null) {
                throw new ApiException("商品轮播图-图片排序值不能为空！");
            }
            productImgRequest.setType("banner");
            productImgRequest.setProductId(goodsRequest.getId());
        }
        List<ProductImgResponse> infoList = goodsRequest.getInfoList();
        if (!CollectionUtils.isEmpty(infoList)) {
            for (ProductImgResponse productImgRequest : infoList) {
                if (productImgRequest.getSort() == null) {
                    throw new ApiException("商品主图-图片排序值不能为空！");
                }
                productImgRequest.setType("info");
                productImgRequest.setProductId(goodsRequest.getId());
            }
        }
        addList.addAll(infoList);
        addList.addAll(bannerList);
        productDao.saveImg(addList);
    }

    public void updateProductSpecNew(Integer productId,List<ProductSpecResponse> specList,Integer isSync) throws Exception{
        try {
            List<Integer> supplyIdList = specList.stream().map(ProductSpecResponse::getSupplyId).collect(Collectors.toList());
            List<ProductSpecResponse> productSpecsList =null;
            if (isSync !=null && isSync ==2) {
                productSpecsList = productDao.selectBySupIdList(supplyIdList);
            }

            if (specList.size() > 0) {
                for (ProductSpecResponse productSpecResponse : specList) {
                    if (!CollectionUtils.isEmpty(productSpecsList)) {
                        List<ProductSpecResponse> otherSpecList = productSpecsList.stream().filter(item -> item.getSupplyId().equals(productSpecResponse.getSupplyId())
                                && productId.equals(item.getProductId())).collect(Collectors.toList());
                        if (!CollectionUtils.isEmpty(otherSpecList)) {
                            for (ProductSpecResponse otherSpec : otherSpecList) {
                                Integer otherSpecId = otherSpec.getId();
                                BeanUtils.copyProperties(productSpecResponse,otherSpec);
                                otherSpec.setId(otherSpecId);
                                productDao.updateSpecInfoApp(otherSpec);
                            }
                        }
                    }
                }
            }
        }catch (Exception e) {
            log.error("修改商品规格失败：{}",e.getMessage());
            throw e;
        }

    }


    public void saveProductImg(ProductUpdateRequest goodsRequest) {
        List<ProductImgResponse> addList = new ArrayList<>();

        List<ProductImgResponse> infoList = goodsRequest.getInfoList();
        if (!CollectionUtils.isEmpty(infoList)) {
            for (ProductImgResponse productImgRequest : infoList) {
                if (productImgRequest.getSort() == null) {
                    throw new ApiException("商品主图-图片排序值不能为空！");
                }
                productImgRequest.setType("info");
                productImgRequest.setProductId(goodsRequest.getId());
            }
        }
        addList.addAll(infoList);
        productDao.saveImg(addList);
    }

    public ProductCopyHistory saveHistory(String request,Integer modifyType) {
        ProductCopyHistory productCopyHistory = new ProductCopyHistory();
        productCopyHistory.setCreateTime(new Date());
        productCopyHistory.setModifyType(modifyType);
        productCopyHistory.setRequestParam(JSON.toJSONString(request));
        productCopyHistory.setStatus(1);
        productCopyHistoryMapper.insert(productCopyHistory);
        return productCopyHistory;
    }



    @RabbitListener(queuesToDeclare = @Queue(value = QueueConstants.ADD_PRODUCT_REVIEWS, durable = "true"))
    public void addProductReviews(String addProductReviewsStr, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag, Channel channel) {
        log.info("收到一条消息addProductReviews消息：" + addProductReviewsStr+"");
        ProductReviewsAddRequest productReviewsAddRequest = JSONObject.parseObject(addProductReviewsStr, ProductReviewsAddRequest.class);
        ProductReviews reviews = new ProductReviews();
        reviews.setNickname(productReviewsAddRequest.getNickname());
        reviews.setContent(productReviewsAddRequest.getContent());
        reviews.setProductId(Integer.parseInt(productReviewsAddRequest.getProductId()));
        reviews.setProductName(productReviewsAddRequest.getProductName());
        if (!CollectionUtils.isEmpty(productReviewsAddRequest.getProductImgList())) {
            reviews.setProductImg(productReviewsAddRequest.getProductImgList().stream().collect(Collectors.joining(",")));
        }
        productReviewsMapper.insertRandomTime(reviews);
    }


    @RabbitListener(queuesToDeclare = @Queue(value = QueueConstants.UPDATE_PRODUCT_REVIEWS, durable = "true"))
    public void updateProductReviews(String updateProductReviewsStr, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag, Channel channel) {
        log.info("收到一条消息updateProductReviewsStr消息：" + updateProductReviewsStr+"");
        ProductReviewsUpdateRequest request = JSONObject.parseObject(updateProductReviewsStr, ProductReviewsUpdateRequest.class);
        if (null != request && request.getId()!=null) {
            productReviewsMapper.updateProductReviews(request.getId(),request.getContent(),request.getNickname(),request.getIsShow());
        }
    }

    @RabbitListener(queuesToDeclare = @Queue(value = QueueConstants.CHANNEL_ADD_QUEUE, durable = "true"))
    public void addChannelAutoCreateShortUrl(String channelStr, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag, Channel channel) {
        log.info("收到一条消息addChannelAutoCreateShortUrl消息：" + channelStr+"");
        //时间累计
        Calendar gc = new GregorianCalendar();
        gc.setTime(new Date());
        //设置短链的失效时间
        gc.add(GregorianCalendar.MINUTE, 15*24*60);
        Map<String,String> map = JSONObject.parseObject(channelStr, Map.class);
        DlListVo dlList = new DlListVo();
        dlList.setCreateAdmin(map.get("adminName"));
        dlList.setDomain(map.get("domain"));
        dlList.setUrl(map.get("url"));
        dlList.setTitle(map.get("title"));
        dlList.setForever(0);
        dlList.setExpirationDate(gc.getTime());
        String resultJson = HttpClientUtil.doPostJson(url+"/admin/add", JSON.toJSONString(dlList));
    }

}
